package com.dsj.gxrd.modules.activity.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsj.gxrd.modules.activity.domain.dto.RdNewsApprovalDto;
import com.dsj.gxrd.modules.activity.domain.dto.RdNewsDto;
import com.dsj.gxrd.modules.activity.domain.entity.RdApproval;
import com.dsj.gxrd.modules.activity.domain.entity.RdNews;
import com.dsj.gxrd.modules.activity.domain.query.RdNewsQuery;
import com.dsj.gxrd.modules.activity.domain.vo.RdNewsVo;
import com.dsj.gxrd.modules.activity.mapper.RdNewsMapper;
import com.dsj.gxrd.modules.activity.service.RdApprovalService;
import com.dsj.gxrd.modules.activity.service.RdNewsService;
import com.dsj.gxrd.modules.book.domain.dto.RdFileDto;
import com.dsj.gxrd.modules.book.enums.ApprovalStatus;
import com.dsj.gxrd.modules.book.enums.FileRelationTypeEnum;
import com.dsj.gxrd.modules.book.service.IRdFileService;
import com.dsj.gxrd.modules.people.domain.vo.RdUserInfoVo;
import com.dsj.gxrd.modules.people.service.RdUserInfoService;
import com.dsj.gxrd.utils.BaseEntityHandlerUtils;
import com.ruoyi.common.core.constant.RoleConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;


/**
 * @author songpin566
 * @date 2023/10/07
 **/
@Service
public class RdNewsServiceImpl extends ServiceImpl<RdNewsMapper, RdNews> implements RdNewsService {

    @Autowired
    private IRdFileService rdFileService;

    @Autowired
    private RdUserInfoService rdUserInfoService;

    @Autowired
    private RdApprovalService approvalService;

    @Override
    public List<RdNewsVo> selectRdNewsList(RdNewsQuery rdNewsQuery) {
        if (rdNewsQuery.getActiveTime() != null && rdNewsQuery.getActiveTime()[1] != null) {
            Date endDate = rdNewsQuery.getActiveTime()[1];
            Calendar c = Calendar.getInstance();
            c.setTime(endDate);
            c.set(Calendar.HOUR_OF_DAY, 23);
            c.set(Calendar.MINUTE, 59);
            c.set(Calendar.SECOND, 59);
            rdNewsQuery.getActiveTime()[1] = c.getTime();
        }
        List<RdNewsVo> list;
        String isGxrdcwh = rdNewsQuery.getIsGxrdcwh();
        if ("Y".equalsIgnoreCase(isGxrdcwh)) {
            list = this.baseMapper.selectRdNewsList2(rdNewsQuery);
        } else {
            list = this.baseMapper.selectRdNewsList(rdNewsQuery);
        }

        for (RdNewsVo rdNewsVo : list) {
            Long approvalBy = rdNewsVo.getApprovalUserId();
            RdUserInfoVo approval = rdUserInfoService.selectUserById(approvalBy);
            if (approval != null) {
                rdNewsVo.setApprovalByName(approval.getName());
            }
            if (rdNewsVo.getCreateBy() != null) {
                RdUserInfoVo user = rdUserInfoService.selectUserById(rdNewsVo.getCreateBy());
                if (user != null) {
                    rdNewsVo.setCreateByName(user.getName());
                }
            }
            //List<RdFileDto> rdFile = rdFileService.listFiles(rdNewsVo.getRdNewsId(), FileRelationTypeEnum.NEWS_IMAGE);
            //rdNewsVo.setFileList(rdFile);
        }
        return list;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertRdNews(RdNewsDto rdNewsDto) {
        if (!"Y".equalsIgnoreCase(rdNewsDto.getIsGxrdcwh())) {
            rdNewsDto.setIsGxrdcwh("N");
        }
        RdNews rdNews = BeanUtils.copyProperties(rdNewsDto, RdNews.class);
        BaseEntityHandlerUtils.fastSetBaseEntity(rdNews, SecurityUtils.getLoginUser(), false);
        boolean save = save(rdNews);
        rdFileService.saveFileBatch(rdNewsDto.getFileList(), rdNews.getRdNewsId(), FileRelationTypeEnum.NEWS_IMAGE);
        //添加对应审批数据 赣县人大常委会不需要审核
        if(!"Y".equalsIgnoreCase(rdNewsDto.getIsGxrdcwh())){
            RdApproval approval = new RdApproval(
                    3,
                    rdNews.getRdNewsId(),
                    ApprovalStatus.WAIT_APPROVAL.getCode(),
                    0, RoleConstants.VILLAGES_REP_KEY,
                    1);
            approvalService.save(approval);
        }
        return save;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRdNews(RdNewsDto rdNewsDto) {
        String isGxrdcwh = rdNewsDto.getIsGxrdcwh();
        if (!"Y".equalsIgnoreCase(isGxrdcwh)) {
            RdApproval one = approvalService.lambdaQuery().eq(RdApproval::getBusinessType, 3).eq(RdApproval::getBusinessId, rdNewsDto.getRdNewsId())
                    .eq(RdApproval::getIsCurrent, 1).one();
            Integer approvalStatus = one.getStatus();
            if (approvalStatus == ApprovalStatus.APPROVAL_PASS.getCode() || approvalStatus == ApprovalStatus.APPROVAL_NO_PASS.getCode()) {
                throw new ServiceException("此信息审批通过或驳回，无法修改");
            }
        }else {
            if("Y".equalsIgnoreCase(rdNewsDto.getIsPublish())){
                throw new ServiceException("此信息已经发布，无法修改");
            }
        }
        RdNews rdNews = BeanUtils.copyProperties(rdNewsDto, RdNews.class);
        BaseEntityHandlerUtils.fastSetBaseEntity(rdNews, SecurityUtils.getLoginUser(), true);
        boolean b = updateById(rdNews);
        rdFileService.updateFileBatch(rdNewsDto.getFileList(), rdNewsDto.getRdNewsId(), FileRelationTypeEnum.NEWS_IMAGE);
        return b;
    }

    @Override
    public RdNewsVo getInfo(Long rdNewsId) {
        RdNews rdNews = getById(rdNewsId);
        RdNewsVo rdNewsVo = BeanUtils.copyProperties(rdNews, RdNewsVo.class);
        List<RdFileDto> rdFiles = rdFileService.listFiles(rdNewsId, FileRelationTypeEnum.NEWS_IMAGE);
        rdNewsVo.setFileList(rdFiles);
        return rdNewsVo;
    }

 /*   List<Long>deptIds;
        try {
        AjaxResult list = deptService.list(new SysDept());
        ObjectMapper objectMapper=new ObjectMapper();
        List<SysDept> deptList = objectMapper.readValue(objectMapper.writeValueAsString(list.get("data")), new TypeReference<List<SysDept>>() {
        });
        deptIds=new ArrayList<>();
        getAllChildren(deptList,100L,deptIds);
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    }
    //传部门id获取当前部门所有子部门id
    private void getAllChildren(List<SysDept> deptList,Long deptId,List<Long>deptIds) {
        for (SysDept dept : deptList) {
            //获取下一层子部门id
            if(Objects.equals(deptId, dept.getParentId())){
                deptIds.add(dept.getDeptId());
                getAllChildren(deptList,dept.getDeptId(),deptIds);
            }
        }
    }*/

    @Override
    public AjaxResult approval(RdNewsApprovalDto approvalDto) {
        //如果已经是审核通过和审核驳回，则不让再审核
        //1.首先验证是否有审核权限
        Set<String> roles = SecurityUtils.getLoginUser().getRoles();
        if (!StringUtils.containsAny(roles, RoleConstants.VILLAGES_REP_KEY, RoleConstants.VILLAGES_CHAIRMAN_KEY, RoleConstants.DISTRICT_CHIEF_ADMIN_KEY)) {
            return AjaxResult.error("没有权限审核数据!");
        }
        //2.第二步验证如果已经审批通过或驳回了则不允许再审核
        Long rdNewsId = approvalDto.getRdNewsId();
        Integer approvalOpinion = approvalDto.getApprovalOpinion();
        Integer businessType = approvalDto.getBusinessType();
        String remark = approvalDto.getRemark();
        RdApproval one = approvalService.lambdaQuery()
                .eq(RdApproval::getBusinessType, businessType)
                .eq(RdApproval::getBusinessId, rdNewsId)
                .eq(RdApproval::getIsCurrent, 1).one();
        Integer approvalStatus = one.getStatus();
        //查找最新的审核状态
        if (approvalStatus == ApprovalStatus.APPROVAL_NO_PASS.getCode() || approvalStatus == ApprovalStatus.APPROVAL_PASS.getCode()) {
            return AjaxResult.error("已经审批通过或驳回!无法再次审核!");
        }
        //3.第三步验证是否是按 乡镇人大代表->乡镇人大主席->区人大总管理员这顺序审核 Constants.VILLAGES_REP_KEY role_key"006"
        //查询当前审核人key
        String currentRoleKey = one.getCurrentApprovalRole();
        one.setApprovalTime(LocalDateTime.now());
        one.setApprovalUserId(SecurityUtils.getLoginUser().getSysUser().getUserId());
        one.setApprovalContent(remark);
        if (roles.contains(currentRoleKey)) {
            //是当前审核人，如果审核驳回
            if (ApprovalStatus.APPROVAL_NO_PASS.getCode() == approvalOpinion) {
                //修改审核状态为2
                one.setStatus(ApprovalStatus.APPROVAL_NO_PASS.getCode());
                approvalService.lambdaUpdate()
                        .eq(RdApproval::getBusinessType, businessType)
                        .eq(RdApproval::getBusinessId, rdNewsId)
                        .set(RdApproval::getStatus, ApprovalStatus.APPROVAL_NO_PASS.getCode()).update();
                //修改当条数据的审核时间 审核人 审核内容等信息
            } else {
                RdApproval approval = new RdApproval(businessType,
                        rdNewsId,
                        ApprovalStatus.WAIT_APPROVAL.getCode(),
                        0,
                        1);
                switch (currentRoleKey) {
                    case RoleConstants.VILLAGES_REP_KEY:
                        //则设置下一个审核人007，如果审核通过
                        //修改原最新审核为已经审核的旧数据0
                        one.setIsCurrent(0);
                        approval.setCurrentApprovalRole(RoleConstants.VILLAGES_CHAIRMAN_KEY);
                        approvalService.save(approval);
                        //rdNews.setCurrentRoleKey(RoleConstants.VILLAGES_CHAIRMAN_KEY);
                        break;
                    case RoleConstants.VILLAGES_CHAIRMAN_KEY:
                        one.setIsCurrent(0);
                        approval.setCurrentApprovalRole(RoleConstants.DISTRICT_CHIEF_ADMIN_KEY);
                        approvalService.save(approval);
                        break;
                    default:
                        //最后一个审批人，审核通过 修改所有状态为审批通过
                        one.setStatus(ApprovalStatus.APPROVAL_PASS.getCode());
                        approvalService.lambdaUpdate().eq(RdApproval::getBusinessType, businessType).eq(RdApproval::getBusinessId, rdNewsId)
                                .set(RdApproval::getStatus, ApprovalStatus.APPROVAL_PASS.getCode()).update();
                        break;
                }
            }
            return approvalService.updateById(one) ? AjaxResult.success("审核成功") : AjaxResult.error("审核失败");
        }
        return AjaxResult.error("不是当前审核人!");
    }

    @Override
    public AjaxResult removes(List<Long> rdNewsIds) {
        return removeBatchByIds(rdNewsIds) ? AjaxResult.success("删除成功") : AjaxResult.error();
    }


}
